package com.github.shiro.controller;

import com.github.shiro.entity.User;
import com.github.shiro.service.IUserService;
import com.github.shiro.utils.Constant;
import com.github.shiro.utils.JWTUtil;
import com.github.shiro.utils.RedisUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * @program: shiro
 * @description: login&logout controller
 * @author: ruiyanglee
 * @create: 2020-07-23 16:16
 **/

@RestController
@RequestMapping("/auth")
public class ShiroController {

    @Resource
    private IUserService userService;
    @Resource
    private RedisUtil redisUtil;

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public Map<String, String> login(@RequestParam String username,
                                     @RequestParam String password,
                                     HttpServletResponse response) {
        HashMap<String, String> map = new HashMap<>(6);
        User currentUser = userService.findByUsername(username);
        if (currentUser == null) {
            map.put("result", "用户名不存在");
            map.put("code", "401");
            return map;
        }
        String salt = currentUser.getPrivateSalt();
        Md5Hash md5Hash = new Md5Hash(password, salt, 1);
        if (!md5Hash.toString().equals(currentUser.getPassword())) {
            map.put("result", "密码错误");
            map.put("code", "401");
            return map;
        }

        try {
            String token = JWTUtil.sign(username);
            response.setHeader("Authorization", token.toString());
            response.setHeader("Access-Control-Expose-Headers", "Authorization");
            map.put("result", "success");
            map.put("code", "200");
            map.put("token", token);
            // 设置token缓存有效时间
            redisUtil.set(Constant.TOKEN_PREFIX + username, token);
            redisUtil.expire(Constant.TOKEN_PREFIX + username, Constant.EXPIRE_TIME);

            return map;
        } catch (IncorrectCredentialsException e) {
            map.put("result", "fail");
            map.put("code", "400");
        }
        return map;
    }

    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public Map<String, String> logout(HttpServletRequest request) {
        String token = request.getHeader(Constant.TOKEN);
        String username = JWTUtil.getUsername(token);
        redisUtil.del(Constant.TOKEN_PREFIX + username);
        Map<String, String> map = new HashMap<>();
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        map.put("result", "退出成功");
        map.put("code", "302");
        return map;
    }
}
